﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace YAPL.Language.Ast {
	public abstract class Expression {
		private readonly Guid _uniqueId;
		private readonly ExpressionType _nodeType;
		private readonly Type _type;
		private readonly bool _canRead;
		private readonly bool _canWrite;

		protected Expression(ExpressionType nodeType, Type type) : this(nodeType, type, true, true) {}

		protected Expression(ExpressionType nodeType, Type type, bool canRead, bool canWrite) {
			_uniqueId = Guid.NewGuid();
			_nodeType = nodeType;
			_type = type;
			_canRead = canRead;
			_canWrite = canWrite;
		}

		/// <summary>
		/// gets expression type
		/// </summary>
		public ExpressionType NodeType {
			get { return _nodeType; }
		}

		/// <summary>
		/// gets return type of the expression
		/// </summary>
		public Type Type {
			get { return _type; }
		}

		/// <summary>
		/// determines wether expression can be read
		/// </summary>
		public bool CanRead {
			get { return _canRead; }
		}

		/// <summary>
		/// determines wethe expression can be written
		/// </summary>
		public bool CanWrite {
			get { return _canWrite; }
		}

		public Guid ID {
			get { return _uniqueId; }
		}

		public abstract bool NodeEquals(Expression other);
		public abstract bool RewriteChild(Expression child, Expression newExpression);
	}
}
